import os
import json
import uuid
import wave
import requests
from PyQt5.QtWidgets import (QMainWindow, QWidget, QVBoxLayout, QHBoxLayout, QGroupBox, QLabel, 
                            QPushButton, QTextEdit, QGridLayout, QListWidget, QListWidgetItem, 
                            QProgressBar, QMessageBox,  QApplication)
from PyQt5.QtCore import Qt, QThread, pyqtSignal, QTimer, QDateTime, QUrl
from PyQt5.QtGui import QFont, QPixmap, QColor
from PyQt5.QtMultimedia import QSound
import pyaudio
from PyQt5.QtChart import QChart, QPieSeries, QPieSlice,QChartView
import platform

# 配置
BACKEND_URL = "http://localhost:5000"
UPLOAD_FOLDER = "uploads"
GENERATED_FOLDER = "generated"
FA_FONT_FAMILY = "FontAwesome"
STYLE_MAPPING = {
    "ink": "水墨", "gongbi": "工笔", "xieyi": "写意",
    "shanshui": "青绿", "flower": "浅绛", "calligraphy": "书法"
}

os.makedirs(UPLOAD_FOLDER, exist_ok=True)
os.makedirs(GENERATED_FOLDER, exist_ok=True)

# 录音线程
class RecordThread(QThread):
    finished = pyqtSignal(list)
    
    def __init__(self, stream, frames, chunk):
        super().__init__()
        self.stream = stream
        self.frames = frames
        self.chunk = chunk
        self.running = True
    
    def run(self):
        while self.running:
            data = self.stream.read(self.chunk)
            self.frames.append(data)
    
    def stop(self):
        self.running = False
        self.wait()
        self.finished.emit(self.frames)

# 语音识别线程
class SpeechRecognitionThread(QThread):
    finished = pyqtSignal(str, float)
    error = pyqtSignal(str)

    def __init__(self, audio_path):
        super().__init__()
        self.audio_path = audio_path

    def run(self):
        try:
            # 检查后端连接
            try:
                response = requests.get(f"{BACKEND_URL}/", timeout=30)
                if response.status_code != 200:
                    self.error.emit("后端服务未正常响应")
                    return
            except requests.exceptions.ConnectionError:
                self.error.emit("无法连接到后端服务，请确保后端已启动")
                return
            except Exception as e:
                self.error.emit(f"连接检查失败: {str(e)}")
                return
            
            # 语音识别请求（超时改为60秒）
            url = f"{BACKEND_URL}/api/voice-to-text"
            with open(self.audio_path, "rb") as f:
                audio_data = f.read()
                response = requests.post(
                    url, 
                    data=audio_data, 
                    headers={'Content-Type': 'audio/wav'}, 
                    timeout=60  # 超时时间调整为60秒
                )
                data = response.json()
                if data["code"] == 200:
                    self.finished.emit(data["data"]["text"], data["data"]["accuracy"])
                else:
                    self.error.emit(f"识别失败：{data['msg']}")
        except Exception as e:
            self.error.emit(f"网络错误：{str(e)}")

# 画作生成线程
class PaintingThread(QThread):
    finished = pyqtSignal(dict)
    progress = pyqtSignal(str)
    error = pyqtSignal(str)

    def __init__(self, input_text, style):
        super().__init__()
        self.input_text = input_text
        self.style = style

    def run(self):
        try:
            # 检查后端连接
            try:
                response = requests.get(f"{BACKEND_URL}/", timeout=30)
                if response.status_code != 200:
                    self.error.emit("后端服务未正常响应")
                    return
            except requests.exceptions.ConnectionError:
                self.error.emit("无法连接到后端服务，请确保后端已启动")
                return
            except Exception as e:
                self.error.emit(f"连接检查失败: {str(e)}")
                return
            
            url = f"{BACKEND_URL}/api/generate-painting"
            self.progress.emit("正在处理请求...")
            data = {
                "input_text": self.input_text,
                "style": self.style
            }
            response = requests.post(url, json=data, timeout=600)
            self.finished.emit(response.json())
        except Exception as e:
            self.finished.emit({"code": 500, "msg": f"请求失败：{str(e)}", "data": {}})

# 主窗口类
class ChinesePaintingWindow(QMainWindow):
    def __init__(self):
        super().__init__()
        self.setWindowTitle("声画 - 语音生成中国书画")
        self.setGeometry(100, 100, 1200, 800)
        self.current_painting_id = None
        self.is_recording = False
        self.audio_recorder = None
        self.creation_stats = {
            "total": 0,
            "styles": {"ink": 0, "gongbi": 0, "xieyi": 0, "shanshui": 0, "flower": 0, "calligraphy": 0},
            "history": []
        }
        self.confirmed_text = ""
        self.current_description = ""  # 存储当前画作描述
        self.load_creation_stats()
        self.init_ui()
        self.init_chart()
        self.update_stats_display()
        
        # 录音相关
        self.audio = pyaudio.PyAudio()
        self.frames = []
        self.recording = False
        self.stream = None

    def init_ui(self):
        # 中心部件与主布局
        central_widget = QWidget()
        self.setCentralWidget(central_widget)
        main_layout = QVBoxLayout(central_widget)
        main_layout.setContentsMargins(20, 20, 20, 20)
        main_layout.setSpacing(20)

        # 顶部标题区
        top_layout = QVBoxLayout()
        self.jzh_label = QLabel("江知海")
        self.jzh_label.setAlignment(Qt.AlignCenter)
        self.jzh_label.setFont(QFont("STKaiti", 24, QFont.Bold))
        self.jzh_label.setStyleSheet("color: #8B4513;")
        top_layout.addWidget(self.jzh_label)

        self.title_label = QLabel(f" 声画 - 用声音描绘中国传统书画之美")
        self.title_label.setAlignment(Qt.AlignCenter)
        title_font = QFont(FA_FONT_FAMILY, 20, QFont.Bold)
        title_font.setFamily(f"STSong, {FA_FONT_FAMILY}")
        self.title_label.setFont(title_font)
        self.title_label.setStyleSheet("color: #8B4513;")
        top_layout.addWidget(self.title_label)
        main_layout.addLayout(top_layout)

        # 核心内容区（左右布局）
        core_layout = QHBoxLayout()
        core_layout.setSpacing(20)

        # 左侧：控制面板 + 统计
        left_layout = QVBoxLayout()
        left_layout.setSpacing(20)

        # 控制面板
        control_group = QGroupBox("创作控制")
        control_group.setFont(QFont("STSong", 14, QFont.Bold))
        control_group.setStyleSheet("""
            QGroupBox { color: #8B4513; border: 2px solid #8B4513; border-radius: 8px; margin-top: 10px; }
            QGroupBox::title { subcontrol-origin: margin; left: 10px; }
        """)
        control_layout = QVBoxLayout(control_group)
        control_layout.setSpacing(15)

        # 语音描述模块
        voice_layout = QVBoxLayout()
        voice_label = QLabel("语音描述")
        voice_label.setFont(QFont("STSong", 12))
        voice_layout.addWidget(voice_label)

        self.record_btn = QPushButton(f"🎤 开始录音")
        self.record_btn.setFont(QFont(FA_FONT_FAMILY, 12))
        self.record_btn.setStyleSheet("""
            QPushButton { background-color: #CD5C5C; color: white; border-radius: 20px; padding: 10px; }
            QPushButton:hover { background-color: #B22222; }
            QPushButton:disabled { background-color: #D3D3D3; }
        """)
        self.record_btn.clicked.connect(self.toggle_recording)
        voice_layout.addWidget(self.record_btn, alignment=Qt.AlignCenter)

        self.record_status = QLabel("点击按钮开始录音")
        self.record_status.setFont(QFont("STSong", 10))
        self.record_status.setAlignment(Qt.AlignCenter)
        self.record_status.setStyleSheet("color: #2F4F4F;")
        voice_layout.addWidget(self.record_status)
        control_layout.addLayout(voice_layout)

        # 识别结果模块
        result_layout = QVBoxLayout()
        result_label = QLabel("识别结果（可编辑修改）")
        result_label.setFont(QFont("STSong", 12))
        result_layout.addWidget(result_label)

        self.result_edit = QTextEdit("等待语音输入...")
        self.result_edit.setFont(QFont("STSong", 11))
        self.result_edit.setStyleSheet("""
            QTextEdit { background-color: #F5F5DC; border: 1px solid #8B4513; border-radius: 4px; padding: 5px; }
        """)
        self.result_edit.setReadOnly(False)
        self.result_edit.setFixedHeight(80)
        self.result_edit.textChanged.connect(self.on_text_changed)
        result_layout.addWidget(self.result_edit)

        # 确认按钮布局
        confirm_btn_layout = QHBoxLayout()
        self.confirm_text_btn = QPushButton(f"✓ 确认文本")
        self.confirm_text_btn.setFont(QFont(FA_FONT_FAMILY, 10))
        self.confirm_text_btn.setStyleSheet("""
            QPushButton { background-color: #2E8B57; color: white; border-radius: 4px; padding: 5px 10px; }
            QPushButton:hover { background-color: #3CB371; }
            QPushButton:disabled { background-color: #D3D3D3; }
        """)
        self.confirm_text_btn.setEnabled(False)
        self.confirm_text_btn.clicked.connect(self.confirm_text)
        
        clear_btn = QPushButton(f"🧽 清空")
        clear_btn.setFont(QFont(FA_FONT_FAMILY, 10))
        clear_btn.setStyleSheet("""
            QPushButton { background-color: transparent; color: #8B4513; border: none; }
            QPushButton:hover { color: #CD5C5C; }
        """)
        clear_btn.clicked.connect(self.clear_text)
        
        confirm_btn_layout.addWidget(self.confirm_text_btn)
        confirm_btn_layout.addStretch()
        confirm_btn_layout.addWidget(clear_btn)
        result_layout.addLayout(confirm_btn_layout)
        control_layout.addLayout(result_layout)

        # 风格选择模块
        style_layout = QVBoxLayout()
        style_label = QLabel("风格选择")
        style_label.setFont(QFont("STSong", 12))
        style_layout.addWidget(style_label)

        style_grid = QGridLayout()
        style_grid.setSpacing(8)
        self.style_btns = {
            "ink": QPushButton("水墨画"),
            "gongbi": QPushButton("工笔画"),
            "xieyi": QPushButton("写意画"),
            "shanshui": QPushButton("山水画"),
            "flower": QPushButton("花鸟画"),
            "calligraphy": QPushButton("书法")
        }
        for i, (style, btn) in enumerate(self.style_btns.items()):
            btn.setFont(QFont("STSong", 11))
            btn.setStyleSheet("""
                QPushButton { background-color: #D2B48C30; color: #2F4F4F; border-radius: 4px; padding: 5px; }
                QPushButton:hover { background-color: #D2B48C60; }
                QPushButton:checked { background-color: #D2B48C60; font-weight: bold; }
            """)
            btn.setCheckable(True)
            btn.clicked.connect(lambda _, s=style: self.select_style(s))
            row = i // 3
            col = i % 3
            style_grid.addWidget(btn, row, col)
        self.style_btns["ink"].setChecked(True)
        self.selected_style = "ink"
        style_layout.addLayout(style_grid)
        control_layout.addLayout(style_layout)

        # 生成按钮
        self.generate_btn = QPushButton(f"✨ 生成画作")
        self.generate_btn.setFont(QFont(FA_FONT_FAMILY, 13, QFont.Bold))
        self.generate_btn.setStyleSheet("""
            QPushButton { background-color: #8B4513; color: white; border-radius: 4px; padding: 10px; }
            QPushButton:hover { background-color: #654321; }
            QPushButton:disabled { background-color: #D3D3D3; }
        """)
        self.generate_btn.clicked.connect(self.generate_painting)
        self.generate_btn.setEnabled(False)
        control_layout.addWidget(self.generate_btn, alignment=Qt.AlignCenter)
        left_layout.addWidget(control_group)

        # 创作统计
        stats_group = QGroupBox("创作统计")
        stats_group.setFont(QFont("STSong", 14, QFont.Bold))
        stats_group.setStyleSheet("""
            QGroupBox { color: #8B4513; border: 2px solid #8B4513; border-radius: 8px; margin-top: 10px; }
            QGroupBox::title { subcontrol-origin: margin; left: 10px; }
        """)
        stats_layout = QVBoxLayout(stats_group)
        stats_layout.setSpacing(15)

        self.chart_view = QChartView()
        self.chart_view.setFixedHeight(200)
        stats_layout.addWidget(self.chart_view)

        stats_grid = QGridLayout()
        total_label = QLabel("总创作次数：")
        total_label.setFont(QFont("STSong", 11))
        self.total_count = QLabel("0")
        self.total_count.setFont(QFont("STSong", 14, QFont.Bold))
        self.total_count.setStyleSheet("color: #8B4513;")
        fav_label = QLabel("最常用风格：")
        fav_label.setFont(QFont("STSong", 11))
        self.fav_style = QLabel("水墨画")
        self.fav_style.setFont(QFont("STSong", 14, QFont.Bold))
        self.fav_style.setStyleSheet("color: #8B4513;")
        stats_grid.addWidget(total_label, 0, 0)
        stats_grid.addWidget(self.total_count, 0, 1)
        stats_grid.addWidget(fav_label, 1, 0)
        stats_grid.addWidget(self.fav_style, 1, 1)
        stats_layout.addLayout(stats_grid)
        left_layout.addWidget(stats_group)
        core_layout.addLayout(left_layout, stretch=1)

        # 右侧：作品展示 + 历史
        right_layout = QVBoxLayout()
        right_layout.setSpacing(20)

        # 作品展示
        paint_group = QGroupBox("作品展示")
        paint_group.setFont(QFont("STSong", 14, QFont.Bold))
        paint_group.setStyleSheet("""
            QGroupBox { color: #8B4513; border: 2px solid #8B4513; border-radius: 8px; margin-top: 10px; }
            QGroupBox::title { subcontrol-origin: margin; left: 10px; }
        """)
        paint_layout = QVBoxLayout(paint_group)
        paint_layout.setSpacing(15)

        self.paint_container = QLabel()
        self.paint_container.setStyleSheet("""
            QLabel { background-color: #F5F5DC; border: 1px solid #8B4513; border-radius: 4px; }
        """)
        self.paint_container.setAlignment(Qt.AlignCenter)
        self.paint_container.setFixedSize(600, 400)
        self.empty_label = QLabel(f"🎨\n生成的画作将显示在这里")
        self.empty_label.setFont(QFont(FA_FONT_FAMILY, 12))
        self.empty_label.setAlignment(Qt.AlignCenter)
        self.empty_label.setStyleSheet("color: #2F4F4F80;")
        self.paint_container.setLayout(QVBoxLayout())
        self.paint_container.layout().addWidget(self.empty_label)
        paint_layout.addWidget(self.paint_container)

        # 描述文本显示区域
        self.desc_text = QTextEdit()
        self.desc_text.setFont(QFont("STSong", 11))
        self.desc_text.setStyleSheet("background-color: #F5F5DC; border: 1px solid #8B4513; border-radius: 4px; padding: 5px;")
        self.desc_text.setReadOnly(True)
        self.desc_text.setFixedHeight(80)
        paint_layout.addWidget(self.desc_text)

        # 操作按钮（新增播报按钮）
        btn_layout = QHBoxLayout()
        self.save_btn = QPushButton(f"💾 保存画作")
        self.save_btn.setFont(QFont(FA_FONT_FAMILY, 11))
        self.save_btn.setStyleSheet("""
            QPushButton { background-color: #2E8B57; color: white; border-radius: 4px; padding: 5px 10px; }
            QPushButton:hover { background-color: #3CB371; }
            QPushButton:disabled { background-color: #D3D3D3; }
        """)
        self.save_btn.setEnabled(False)
        self.save_btn.clicked.connect(self.save_painting)

        self.regenerate_btn = QPushButton(f"🔄 重新生成")
        self.regenerate_btn.setFont(QFont(FA_FONT_FAMILY, 11))
        self.regenerate_btn.setStyleSheet("""
            QPushButton { background-color: #8B4513; color: white; border-radius: 4px; padding: 5px 10px; }
            QPushButton:hover { background-color: #654321; }
            QPushButton:disabled { background-color: #D3D3D3; }
        """)
        self.regenerate_btn.setEnabled(False)
        self.regenerate_btn.clicked.connect(self.generate_painting)

        self.speak_btn = QPushButton(f"🔊 播报描述")
        self.speak_btn.setFont(QFont(FA_FONT_FAMILY, 11))
        self.speak_btn.setStyleSheet("""
            QPushButton { background-color: #1E90FF; color: white; border-radius: 4px; padding: 5px 10px; }
            QPushButton:hover { background-color: #4682B4; }
            QPushButton:disabled { background-color: #D3D3D3; }
        """)
        self.speak_btn.setEnabled(False)
        self.speak_btn.clicked.connect(self.play_description)

        btn_layout.addWidget(self.save_btn)
        btn_layout.addWidget(self.regenerate_btn)
        btn_layout.addWidget(self.speak_btn)
        paint_layout.addLayout(btn_layout)
        right_layout.addWidget(paint_group)

        # 创作历史
        history_group = QGroupBox("创作历史")
        history_group.setFont(QFont("STSong", 14, QFont.Bold))
        history_group.setStyleSheet("""
            QGroupBox { color: #8B4513; border: 2px solid #8B4513; border-radius: 8px; margin-top: 10px; }
            QGroupBox::title { subcontrol-origin: margin; left: 10px; }
        """)
        history_layout = QVBoxLayout(history_group)
        self.history_list = QListWidget()
        self.history_list.setFont(QFont("STSong", 11))
        self.history_list.setStyleSheet("""
            QListWidget { background-color: #F5F5DC; border: 1px solid #8B4513; border-radius: 4px; padding: 5px; }
            QListWidget::item { padding: 5px; border-bottom: 1px solid #D2B48C30; }
        """)
        self.history_list.itemClicked.connect(self.load_history_item)
        history_layout.addWidget(self.history_list)
        right_layout.addWidget(history_group)
        core_layout.addLayout(right_layout, stretch=2)

        main_layout.addLayout(core_layout)

        # 底部进度条
        self.progress_bar = QProgressBar()
        self.progress_bar.setStyleSheet("""
            QProgressBar { border: 1px solid #8B4513; border-radius: 3px; text-align: center; }
            QProgressBar::chunk { background-color: #8B4513; }
        """)
        self.progress_bar.setVisible(False)
        main_layout.addWidget(self.progress_bar)

    def init_chart(self):
        self.chart = QChart()
        self.chart.setTitle("风格分布")
        self.chart.setTitleFont(QFont("STSong", 12, QFont.Bold))
        self.chart.legend().setAlignment(Qt.AlignBottom)
        self.chart_view.setChart(self.chart)
        self.update_chart()

    def update_chart(self):
        series = QPieSeries()
        styles = {
            "ink": "水墨画", "gongbi": "工笔画", "xieyi": "写意画",
            "shanshui": "山水画", "flower": "花鸟画", "calligraphy": "书法"
        }
        colors = [
            QColor(139, 69, 19), QColor(210, 180, 140),
            QColor(184, 134, 11), QColor(139, 134, 130),
            QColor(245, 222, 179), QColor(222, 184, 135)
        ]
        for i, (key, name) in enumerate(styles.items()):
            count = self.creation_stats["styles"][key]
            if count > 0:
                slice_ = QPieSlice(f"{name} ({count})", count)
                slice_.setBrush(colors[i])
                series.append(slice_)
        self.chart.removeAllSeries()
        if not series.isEmpty():
            self.chart.addSeries(series)

    def update_stats_display(self):
        self.total_count.setText(str(self.creation_stats["total"]))
        styles = self.creation_stats["styles"]
        if any(styles.values()):
            max_style = max(styles, key=lambda k: styles[k])
            style_names = {
                "ink": "水墨画", "gongbi": "工笔画", "xieyi": "写意画",
                "shanshui": "山水画", "flower": "花鸟画", "calligraphy": "书法"
            }
            self.fav_style.setText(style_names[max_style])
        self.history_list.clear()
        for item in reversed(self.creation_stats["history"]):
            list_item = QListWidgetItem(f"{item['date']} - {item['style']}: {item['description'][:20]}...")
            list_item.setData(Qt.UserRole, item["id"])
            self.history_list.addItem(list_item)
        self.update_chart()

    def load_creation_stats(self):
        try:
            if os.path.exists("creation_stats.json"):
                with open("creation_stats.json", "r", encoding="utf-8") as f:
                    self.creation_stats = json.load(f)
        except Exception as e:
            print(f"加载统计数据失败：{e}")
            self.creation_stats = {
                "total": 0,
                "styles": {"ink": 0, "gongbi": 0, "xieyi": 0, "shanshui": 0, "flower": 0, "calligraphy": 0},
                "history": []
            }

    def save_creation_stats(self):
        try:
            with open("creation_stats.json", "w", encoding="utf-8") as f:
                json.dump(self.creation_stats, f, ensure_ascii=False, indent=2)
        except Exception as e:
            print(f"保存统计数据失败：{e}")

    def select_style(self, style):
        self.selected_style = style
        for btn_style, btn in self.style_btns.items():
            btn.setChecked(btn_style == style)

    def toggle_recording(self):
        if not self.recording:
            self.start_recording()
        else:
            self.stop_recording()

    def start_recording(self):
        try:
            self.frames = []
            self.recording = True
            
            # 录音参数
            FORMAT = pyaudio.paInt16
            CHANNELS = 1
            RATE = 16000
            CHUNK = 1024
            
            # 开始录音
            self.stream = self.audio.open(
                format=FORMAT,
                channels=CHANNELS,
                rate=RATE,
                input=True,
                frames_per_buffer=CHUNK
            )
            
            self.record_btn.setText(f"⏹️ 停止录音")
            self.record_btn.setStyleSheet("""
                QPushButton { background-color: #B22222; color: white; border-radius: 20px; padding: 10px; }
                QPushButton:hover { background-color: #8B0000; }
            """)
            self.record_status.setText("正在录音...")
            self.generate_btn.setEnabled(False)
            self.confirm_text_btn.setEnabled(False)
            
            # 启动录音线程
            self.record_thread = RecordThread(self.stream, self.frames, CHUNK)
            self.record_thread.finished.connect(self.on_recording_finished)
            self.record_thread.start()
            
        except Exception as e:
            QMessageBox.critical(self, "录音失败", f"无法开始录音：{str(e)}")
            print(f"录音错误详情: {e}")

    def stop_recording(self):
        if self.recording:
            self.recording = False
            self.record_thread.stop()
            
    def on_recording_finished(self, frames):
        self.record_btn.setText(f"🎤 开始录音")
        self.record_btn.setStyleSheet("""
            QPushButton { background-color: #CD5C5C; color: white; border-radius: 20px; padding: 10px; }
            QPushButton:hover { background-color: #B22222; }
        """)
        self.record_status.setText("正在识别语音...")
        
        # 保存录音文件
        audio_path = os.path.join(UPLOAD_FOLDER, f"recording_{uuid.uuid4()}.wav")
        wf = wave.open(audio_path, 'wb')
        wf.setnchannels(1)
        wf.setsampwidth(self.audio.get_sample_size(pyaudio.paInt16))
        wf.setframerate(16000)
        wf.writeframes(b''.join(frames))
        wf.close()
        
        # 发送到后端识别
        self.recognize_thread = SpeechRecognitionThread(audio_path)
        self.recognize_thread.finished.connect(self.on_speech_recognized)
        self.recognize_thread.error.connect(self.on_recognition_error)
        self.recognize_thread.start()

    def on_recognition_error(self, error_msg):
        QMessageBox.critical(self, "连接错误", error_msg)
        self.record_status.setText("连接失败")
        self.record_btn.setEnabled(True)

    def on_speech_recognized(self, result, accuracy):
        self.result_edit.setText(result)
        self.record_status.setText(f"录音已完成，准确率: {accuracy*100:.1f}%，请确认或修改文本")
        self.confirm_text_btn.setEnabled(True)
        self.generate_btn.setEnabled(False)

    def on_text_changed(self):
        text = self.result_edit.toPlainText().strip()
        if text and text != "等待语音输入...":
            self.confirm_text_btn.setEnabled(True)
        else:
            self.confirm_text_btn.setEnabled(False)

    def confirm_text(self):
        text = self.result_edit.toPlainText().strip()
        if not text or text == "等待语音输入...":
            QMessageBox.warning(self, "输入错误", "请输入有效的描述文本")
            return
            
        self.confirmed_text = text
        self.generate_btn.setEnabled(True)
        self.record_status.setText("文本已确认，可以生成画作")
        QMessageBox.information(self, "确认成功", "文本已确认，点击生成画作按钮开始生成")

    def clear_text(self):
        self.result_edit.clear()
        self.confirmed_text = ""
        self.generate_btn.setEnabled(False)
        self.confirm_text_btn.setEnabled(False)
        self.record_status.setText("已清空文本")

    def generate_painting(self):
        if not self.confirmed_text:
            QMessageBox.warning(self, "输入错误", "请先确认语音描述文本")
            return

        backend_style = STYLE_MAPPING.get(self.selected_style, "水墨")

        self.progress_bar.setVisible(True)
        self.progress_bar.setRange(0, 0)
        self.generate_btn.setEnabled(False)
        self.record_btn.setEnabled(False)
        self.confirm_text_btn.setEnabled(False)

        self.painting_thread = PaintingThread(self.confirmed_text, backend_style)
        self.painting_thread.finished.connect(self.on_painting_generated)
        self.painting_thread.progress.connect(self.update_progress)
        self.painting_thread.error.connect(self.on_painting_error)
        self.painting_thread.start()

    def on_painting_error(self, error_msg):
        QMessageBox.critical(self, "连接错误", error_msg)
        self.progress_bar.setVisible(False)
        self.generate_btn.setEnabled(True)
        self.record_btn.setEnabled(True)
        self.confirm_text_btn.setEnabled(True)

    def update_progress(self, message):
        self.record_status.setText(message)

    def on_painting_generated(self, response):
        self.progress_bar.setVisible(False)
        self.generate_btn.setEnabled(True)
        self.record_btn.setEnabled(True)
        self.confirm_text_btn.setEnabled(True)

        if response.get("code") == 200:
            data = response.get("data", {})
            self.current_painting_id = data.get("painting_path", "").split("/")[-1].split(".")[0]
            try:
                # 获取生成的图像
                image_url = f"{BACKEND_URL}/api/get-painting/{data.get('painting_path', '')}"
                image_data = requests.get(image_url).content
                pixmap = QPixmap()
                pixmap.loadFromData(image_data)
                scaled_pixmap = pixmap.scaled(
                    self.paint_container.size(),
                    Qt.KeepAspectRatio,
                    Qt.SmoothTransformation
                )
                
                # 清除容器旧内容
                for i in reversed(range(self.paint_container.layout().count())):
                    item = self.paint_container.layout().itemAt(i)
                    if item.widget():
                        item.widget().deleteLater()
                
                # 显示新图片
                image_label = QLabel()
                image_label.setPixmap(scaled_pixmap)
                image_label.setAlignment(Qt.AlignCenter)
                self.paint_container.layout().addWidget(image_label)
                
                self.save_btn.setEnabled(True)
                self.regenerate_btn.setEnabled(True)

                # 获取画作描述
                self.get_painting_description(data.get("painting_path", ""))

                # 更新统计
                self.creation_stats["total"] += 1
                self.creation_stats["styles"][self.selected_style] += 1
                self.creation_stats["history"].append({
                    "id": self.current_painting_id,
                    "url": image_url,
                    "description": self.confirmed_text,
                    "style": self.selected_style,
                    "date": QDateTime.currentDateTime().toString("yyyy-MM-dd HH:mm")
                })
                self.save_creation_stats()
                self.update_stats_display()
            except Exception as e:
                QMessageBox.critical(self, "显示失败", f"无法显示画作：{str(e)}")
        else:
            QMessageBox.critical(self, "生成失败", response.get("msg", "未知错误"))

    def get_painting_description(self, painting_path):
        """获取画作描述"""
        try:
            desc_url = f"{BACKEND_URL}/api/get-painting-description/{painting_path}"
            response = requests.get(desc_url)
            if response.status_code == 200:
                data = response.json()
                if data.get("code") == 200:
                    self.current_description = data["data"]["description"]
                    self.speak_btn.setEnabled(True)  # 启用播报按钮
                else:
                    self.record_status.setText("获取画作描述失败")
            else:
                self.record_status.setText("获取画作描述失败")
        except Exception as e:
            print(f"获取描述失败：{e}")
            self.record_status.setText("获取画作描述失败")

    def play_description(self):
        """播放画作描述语音"""
        if not self.current_description:
            return
        
        # 显示描述文本
        self.desc_text.setText(self.current_description)
        
        try:
            tts_url = f"{BACKEND_URL}/api/text-to-voice"
            response = requests.post(tts_url, json={"text": self.current_description})
            if response.status_code == 200 and response.headers.get('content-type') == 'audio/mp3':
                # 保存临时音频并播放
                temp_mp3 = f"temp_desc_{uuid.uuid4()}.mp3"
                with open(temp_mp3, "wb") as f:
                    f.write(response.content)
                
                # 使用系统默认播放器播放
                system = platform.system()
                if system == "Windows":
                    os.system(f"start {temp_mp3}")
                elif system == "Darwin":  # macOS
                    os.system(f"afplay {temp_mp3}")
                else:  # Linux
                    os.system(f"aplay {temp_mp3}")
                
                # 延迟删除临时文件
                QTimer.singleShot(10000, lambda: os.remove(temp_mp3) if os.path.exists(temp_mp3) else None)
            else:
                QMessageBox.warning(self, "播报失败", "语音合成服务异常")
        except Exception as e:
            QMessageBox.warning(self, "播报失败", f"无法播放语音：{str(e)}")

    def save_painting(self):
        if not self.current_painting_id:
            return

        try:
            current_item = next(
                (item for item in self.creation_stats["history"] if item["id"] == self.current_painting_id),
                None
            )
            if not current_item:
                raise Exception("未找到画作信息")

            image_data = requests.get(current_item["url"]).content
            save_path = os.path.join(
                GENERATED_FOLDER,
                f"{self.current_painting_id}_{current_item['style']}.png"
            )
            with open(save_path, "wb") as f:
                f.write(image_data)
            QMessageBox.information(self, "保存成功", f"画作已保存至：\n{save_path}")
        except Exception as e:
            QMessageBox.critical(self, "保存失败", f"无法保存画作：{str(e)}")

    def load_history_item(self, item):
        painting_id = item.data(Qt.UserRole)
        history_item = next(
            (h for h in self.creation_stats["history"] if h["id"] == painting_id),
            None
        )
        if not history_item:
            return

        try:
            image_data = requests.get(history_item["url"]).content
            pixmap = QPixmap()
            pixmap.loadFromData(image_data)
            scaled_pixmap = pixmap.scaled(
                self.paint_container.size(),
                Qt.KeepAspectRatio,
                Qt.SmoothTransformation
            )
            
            # 清除旧内容
            for i in reversed(range(self.paint_container.layout().count())):
                item = self.paint_container.layout().itemAt(i)
                if item.widget():
                    item.widget().deleteLater()
            
            # 显示历史图片
            image_label = QLabel()
            image_label.setPixmap(scaled_pixmap)
            image_label.setAlignment(Qt.AlignCenter)
            self.paint_container.layout().addWidget(image_label)
            
            self.current_painting_id = painting_id
            self.result_edit.setText(history_item["description"])
            self.confirmed_text = history_item["description"]
            self.select_style(history_item["style"])
            self.save_btn.setEnabled(True)
            self.regenerate_btn.setEnabled(True)
            
            # 获取历史画作描述
            painting_path = history_item["url"].split("/api/get-painting/")[-1]
            self.get_painting_description(painting_path)
        except Exception as e:
            QMessageBox.critical(self, "加载失败", f"无法加载历史画作：{str(e)}")

if __name__ == "__main__":
    import sys
    app = QApplication(sys.argv)
    window = ChinesePaintingWindow()
    window.show()
    sys.exit(app.exec_())